﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Core.h".
//-------------------------------------------------------------------

#ifndef _UXS_DYNAMIC_STACK_H
#define _UXS_DYNAMIC_STACK_H

#pragma once

#include "TArray.h"

namespace UX_STL
{
namespace UXTypes
{

	//
	// Dynamic Stack
	//

	template <typename T, typename S = TCopyStrategy<T>, typename A = TAllocator<T> >
	struct TDynStack
	{
	// types
	public:
		typedef S						Strategy;
		typedef A						Allocator;
		typedef T						value_t;
		typedef uni_array<T>			uni_arr;
		typedef uni_array<const T>		uni_c_arr;
		typedef TDynStack<T,S,A>		Self;


	// variables
	private:
		array<T,S,A>	_sArray;


	// methods
	public:
		TDynStack (): _sArray(1, 10) {}
		TDynStack (usize size): _sArray(1, size) {}
		
		TDynStack (const Self &other): _sArray( other._sArray ) {}

		RVALUE_REFERENCE_ONLY( TDynStack (Self &&other): _sArray( ToRValueRef(other._sArray) ) {} )

		~TDynStack () {}

		void SetDefault (const T &tValue)	{ _sArray[0] = tValue; }
		
		bool Pop ();
		
		void Push ();
		void Push (const T &tValue)					{ _sArray.PushBack( tValue ); }

		RVALUE_REFERENCE_ONLY(
			void Push (T &&tValue)					{ _sArray.PushBack( ToRValueRef( tValue ) ); }
		)

		T &  Get ()									{ return _sArray.Back(); }
		const T & Get ()	const					{ return _sArray.Back(); }
		
		void Set (const T &tValue)					{ _sArray.Set( _sArray.LastIndex(), tValue ); }

		usize Size ()	const						{ return _sArray.Capacity(); }
		usize Count ()	const						{ return _sArray.Count(); }
		void  Clear ()								{ _sArray.Resize(1); }
		
		operator		uni_arr ()					{ return uni_arr( _sArray ); }
		operator const	uni_c_arr () const			{ return uni_c_arr( _sArray ); }
	};



	template <typename T, typename S, typename A>
	inline bool TDynStack<T,S,A>::Pop ()
	{
		if ( _sArray.Count() > 1 ) {
			_sArray.PopBack();
			return true;
		}

		WARNING("");
		return false;
	}


	template <typename T, typename S, typename A>
	inline void TDynStack<T,S,A>::Push ()
	{
		T	temp = _sArray.Back();
		_sArray.PushBack( temp );
	}
	
//-------------------------------------------------------------------

}	// UXTypes
}	// UX_STL

#endif	// _UXS_DYNAMIC_STACK_H